
// Copyright (c) 2012, 2013 All Right Reserved, http://hpc.utp.edu.my
// Author: Nordin Zakaria nordinzakaria@gmail.com
// All rights reserved.

#include "WorkSimulation.h"


// Save the value of frac_current_pos to the ckpt file 
void WorkSimulation::do_checkpoint(double frac)
{
}

void WorkSimulation::add(WorkSimulation& work)
	{
	 vector<unsigned int> wlist;
	 work.getWorkerlist(wlist); 
	 comm.add(wlist, work.getComm());
	}

void WorkSimulation::split(vector<WorkSimulation*>& units)
	{
	comm.toText("all.txt");
	system("scp all.txt desktopgrid@192.168.113.200:~/GraphPartitioning");
	system("ssh desktopgrid@192.168.113.200 ./GraphPartitioning/graph ./GraphPartitioning/all.txt ./GraphPartitioning/result.txt");
	system("scp desktopgrid@192.168.113.200:~/GraphPartitioning/result.txt .");

	ifstream infile("result.txt");
	vector<int> results;
	int numunits = 0;
	for (unsigned int i=0; i<workers.size(); i++)
		{
		int cluster;
		infile  >> cluster;
		if (cluster > numunits) numunits = cluster;
		results.push_back(cluster);
		}
	infile.close();

	for (int i=0; i<numunits; i++)
		{
		WorkSimulation *unit = new WorkSimulation();
		unit->addJobs(jobs);
		vector<unsigned int> workerlist;
		for (unsigned int j=0; j<results.size(); j++) {
		     if (results[j] == i) {
		     	 unit->addWorker(workers[j]);
		     	 workerlist.push_back(workers[j].getID());
			 }
		     }

		AdjMatrix subcomm;
		comm.extract(workerlist, subcomm);
		unit->setAdjMatrix(subcomm);	

		unit->setNumsteps(getNumsteps());	
		unit->setCurrNumsteps(getCurrNumsteps());	
		units.push_back(unit);
		}
	}

void WorkSimulation::init(FILE *infile) 
	{
	curr_numsteps = 0;
	numsteps = 0;
	fread(&curr_numsteps,sizeof(unsigned int),1,infile);
	fread(&numsteps,sizeof(unsigned int),1,infile);
	fprintf(stderr, "Curr num steps = %d, total = %d\n", curr_numsteps, numsteps);

	unsigned int numagents = 0;
	unsigned int numjobs = 0;

	fread(&numagents,sizeof(unsigned int),1,infile);
	fprintf(stderr, "Num agents = %d\n", numagents);
	for (unsigned int i=0; i<numagents; i++)
		{
		Worker w;
		w.read(infile);	 
		addWorker(w);
		} 

	fread(&numjobs,sizeof(unsigned int),1,infile);
	fprintf(stderr, "Num jobs = %d\n", numjobs);
	for (unsigned int i=0; i<numjobs; i++)
		{
		Job job;
		job.read(infile);
		addJob(job);	
		}	

	unsigned int totalnumagents = 0;
	fread(&totalnumagents,sizeof(unsigned int),1,infile);
	fprintf(stderr, "Total number of agents = %d\n", totalnumagents);
	comm.init(totalnumagents);
	comm.read(infile);
	}

void WorkSimulation::dump()
	{
	cout << "Num steps: " << curr_numsteps << " " << numsteps << endl;
	cout << "Num workers: " << workers.size() << endl;
	for (unsigned int i=0; i<workers.size(); i++) {
		cout << "Worker " << i << ": " << workers[i] << endl;
		} 
	cout << "Num jobs: " << jobs.size() << endl;
	for (unsigned int i=0; i<jobs.size(); i++) {
		cout << "Job " << i << ": " << jobs[i] << endl;
		}	
	cout << "Total num agents = " << comm.getN() << endl;
	}


void WorkSimulation::dump(string filename)
	{
	ofstream outfile(filename.c_str(), ios::out | ios::binary);

	outfile.write ((char*)&curr_numsteps, sizeof (unsigned int));
	outfile.write ((char*)&numsteps, sizeof (unsigned int));
	cout << "Num steps: " << curr_numsteps << " " << numsteps << endl;

        int wsize = workers.size();
	outfile.write ((char*)&wsize, sizeof (unsigned int));
	cout << "Num workers: " << workers.size() << endl;
	for (unsigned int i=0; i<workers.size(); i++) {
		outfile << workers[i];
		} 

        int jsize = jobs.size();
	outfile.write ((char*)&jsize, sizeof (unsigned int));
	cout << "Num jobs: " << jobs.size() << endl;
	for (unsigned int i=0; i<jobs.size(); i++) {
		outfile << jobs[i];;	
		}	

        int csize = comm.getN();
	outfile.write ((char*)&csize, sizeof (unsigned int));
	outfile << comm;
	cout << "Total num agents = " << comm.getN() << endl;

	outfile.close();
	}

void WorkSimulation::startSimulation()
	{
	  for (;curr_numsteps<numsteps; curr_numsteps++) {
		prestep();
		step();
		poststep();
		}
	}

